﻿Imports System.Net
Imports System.Web
Imports System.IO
Imports System.Xml
Imports System.Xml.XPath
Imports iTunesLib

Module Module1
    Public HBPath As String
    Public mp4boxPath As String
    Public APPath As String
    Public OutPath As String
    Public RemoveAds As Boolean
    Public AutoCrop As Boolean
    Public AutoTVMeta As Boolean
    Public AutoMoviePoster As Boolean
    Public AutoExportiTunes As Boolean
    Public autoDeleteExport As Boolean
    Public OsMajor As Integer
    Public OsMinor As Integer
    Public TempDir As String
    Public AtomicArgs() As String
    Public Posters() As String
    Public Selections(,) As String
    Public SelectedID(1) As String
    Public tvdbAPIID As String = "6111D5FCB5CFCAEF"
    Public tmdbAPIKey As String = "765da88acb6888be871b5ffd1c4a80fa"

    Public Function GetWebData(ByVal URL As String) As Byte()
        Dim Req As HttpWebRequest
        Dim SourceStream As System.IO.Stream
        Dim Response As HttpWebResponse

        Try
            'create a web request to the URL  
            Req = HttpWebRequest.Create(URL)

            'get a response from web site  
            Response = Req.GetResponse()

            'Source stream with requested document  
            SourceStream = Response.GetResponseStream()

            'SourceStream has no ReadAll, so we must read data block-by-block  
            'Temporary Buffer and block size  
            Dim Buffer(4096) As Byte, BlockSize As Integer

            'Memory stream to store data  
            Dim TempStream As New MemoryStream
            Do
                BlockSize = SourceStream.Read(Buffer, 0, 4096)
                If BlockSize > 0 Then TempStream.Write(Buffer, 0, BlockSize)
            Loop While BlockSize > 0

            'return the document binary data  
            Return TempStream.ToArray()
        Catch ex As Exception
            MessageBox.Show(ex.Message & " - " & URL, "GetDataBin")
            'errdw("GetURLDataBin", ex.Message, URL)
        Finally
            'grrr... Using is great, but the command is not in VB.Net  
            SourceStream.Close()
            Response.Close()
        End Try
    End Function

    Public Function GetMetaData(ByVal FileName As String) As String()
        Dim readfile As FileStream
        Dim Character As String
        Dim findtemp As String
        Dim Length As Long
        Dim Position As Long
        Dim find As String = ""
        Dim MetaData() As String
        Dim DataLine() As String
        Dim FileData(5) As String

        'Get length of video file and read the last 8kb to capture SageTV metadata
        readfile = File.OpenRead(FileName)
        Length = readfile.Length
        Position = Length - 8000
        readfile.Position = (Position)

        'Read last 8kb of file byte by byte and convert it to ASCII into a string
        For x As Long = Position To (Length - 1)
            find &= Chr(readfile.ReadByte)
        Next

        'Check to make sure the captured data contains metadata
        If find.Contains("META") Then
            'Strip occurances of "Gÿ" in the string
            find = find.Replace("Gÿ", "")
            'cut beginning and end of string to include only the metadata
            find = find.Substring((find.IndexOf("META") + 4), (find.Length - find.IndexOf("META") - 4))
            find = find.Substring(0, (find.LastIndexOfAny(";") + 1))
            'strip out any unusual characters from string
            For x As Integer = 0 To (find.Length - 1)
                Character = find.Substring(x, 1)
                If (Asc(Character) > 31 And Asc(Character) < 127) Or (Asc(Character) > 127 And Asc(Character) < 166) Then
                    findtemp &= Character
                End If
            Next
            find = findtemp
            'Split captured data by the end of line character ";"
            MetaData = Split(find, ";")
            For x As Integer = 0 To (MetaData.Length - 1)
                'Split data even further by "=" and then capture the Title and ID
                DataLine = Split(MetaData(x), "=")
                If DataLine(0) = "Title" Then
                    FileData(0) = DataLine(1)
                ElseIf DataLine(0) = "ExternalID" Then
                    FileData(2) = DataLine(1)
                End If
            Next
            'If the ID contains "EP" it is a TV show, capture episode name, season number and episode number
            If FileData(2).Contains("EP") Then
                For x As Integer = 0 To (MetaData.Length - 1)
                    DataLine = Split(MetaData(x), "=")
                    If DataLine(0) = "EpisodeName" Then
                        FileData(1) = DataLine(1)
                    End If
                    If DataLine(0) = "SeasonNumber" Then
                        FileData(3) = DataLine(1)
                    End If
                    If DataLine(0) = "EpisodeNumber" Then
                        FileData(4) = DataLine(1)
                    End If
                Next
                'Convert ID format
                If FileData(2).IndexOf("EP") <> 0 Then
                    FileData(2) = Right(FileData(2), (FileData(2).Length - (FileData(2).IndexOf("EP"))))
                End If
            ElseIf FileData(2).Contains("MV") Then 'If ID starts with MV capture the year of the movie
                For x As Integer = 0 To (MetaData.Length - 1)
                    DataLine = Split(MetaData(x), "=")
                    If DataLine(0) = "Year" Then
                        FileData(5) = DataLine(1)
                    End If
                Next
            End If
        End If

        'Close the file and return file metadata
        readfile.Close()
        Return FileData
    End Function

    Public Function GetSeriesID(ByVal SeriesName As String, Optional ByVal RecEpID As String = "0") As Long
        Dim bytearray() As Byte
        Dim xmldata As FileStream
        Dim url As String
        Dim Title As String
        Dim SeriesID As String = "0"
        Dim RecZapID As Long
        Dim zapID As String = ""
        Dim xpathDoc As XPathDocument
        Dim xmlNav As XPathNavigator
        Dim xmlNI As XPathNodeIterator

        'Replace spaces in title with +'s, generate URL, and get XML data
        Title = SeriesName.Replace(" ", "+")
        url = "http://www.thetvdb.com/api/GetSeries.php?seriesname=" & Title & "&language=en"
        bytearray = GetWebData(url)

        'Write XML data to file
        xmldata = New FileStream(TempDir & "temp.xml", FileMode.Create)
        xmldata.Write(bytearray, 0, bytearray.Length)
        xmldata.Close()

        'Open file with XPath
        xpathDoc = New XPathDocument(TempDir & "temp.xml")
        xmlNav = xpathDoc.CreateNavigator

        'If there is no ID from file metadata exactly match title to get TVDB Series ID
        If RecEpID = "0" Then
            xmlNI = xmlNav.Select("//SeriesName[. = '" & SeriesName & "']/parent::node()/seriesid")

            If xmlNI.Count = 1 Then
                xmlNI.MoveNext()
                SeriesID = xmlNI.Current.Value
            Else
                SelectedID(0) = String.Empty
                xmlNI = xmlNav.Select("/Data/Series/SeriesName")
                ReDim Selections((xmlNI.Count - 1), 2)
                Dim x As Integer = 0
                Do While xmlNI.MoveNext
                    Selections(x, 0) = xmlNI.Current.Value
                    x += 1
                Loop
                xmlNI = xmlNav.Select("/Data/Series/FirstAired")
                x = 0
                Do While xmlNI.MoveNext
                    Selections(x, 1) = xmlNI.Current.Value.Substring(0, 4)
                    x += 1
                Loop
                xmlNI = xmlNav.Select("/Data/Series/seriesid")
                x = 0
                Do While xmlNI.MoveNext
                    Selections(x, 2) = xmlNI.Current.Value
                    x += 1
                Loop
                frmTitleSelect.ShowDialog()
                If SelectedID(0) <> String.Empty Then
                    SeriesID = SelectedID(0)
                End If
            End If
            
        Else 'Otherwise try and match the zap2it ID to the recording's ID to get the correct TVDB Series ID
            RecZapID = CLng(RecEpID.Substring(2, (RecEpID.Length - 2)).Substring(0, (RecEpID.Length - 2 - 4)))

            xmlNI = xmlNav.Select("//zap2it_id[contains(.,'" & RecZapID.ToString & "')]/parent::node()/seriesid")

            If xmlNI.Count = 0 Then
                xmlNI = xmlNav.Select("//SeriesName[. = '" & SeriesName & "']/parent::node()/seriesid")
                If xmlNI.Count = 1 Then
                    xmlNI.MoveNext()
                    SeriesID = xmlNI.Current.Value
                Else
                    SelectedID(0) = String.Empty
                    xmlNI = xmlNav.Select("/Data/Series/SeriesName")
                    ReDim Selections((xmlNI.Count - 1), 2)
                    Dim x As Integer = 0
                    Do While xmlNI.MoveNext
                        Selections(x, 0) = xmlNI.Current.Value
                        x += 1
                    Loop
                    xmlNI = xmlNav.Select("/Data/Series/FirstAired")
                    x = 0
                    Do While xmlNI.MoveNext
                        Selections(x, 1) = xmlNI.Current.Value.Substring(0, 4)
                        x += 1
                    Loop
                    xmlNI = xmlNav.Select("/Data/Series/seriesid")
                    x = 0
                    Do While xmlNI.MoveNext
                        Selections(x, 2) = xmlNI.Current.Value
                        x += 1
                    Loop
                    frmTitleSelect.ShowDialog()
                    If SelectedID(0) <> String.Empty Then
                        SeriesID = SelectedID(0)
                    End If
                End If
            Else
                xmlNI.MoveNext()
                SeriesID = xmlNI.Current.Value
            End If
        End If

        'Delete temporary XML file and return the TVDB series ID
        File.Delete(TempDir & "temp.xml")
        Return CLng(SeriesID)
    End Function

    Public Function GetEpisodeData(ByVal EpisodeName As String, ByVal SeriesID As Long) As Integer()
        Dim url As String
        Dim SeriesData() As Byte
        Dim SeriesXML As FileStream
        Dim EpisodeData(1) As Integer
        Dim xpathDoc As XPathDocument
        Dim xmlNav As XPathNavigator
        Dim xmlNI As XPathNodeIterator

        'Use TVDB Series ID to get all episode data for the series
        url = "http://www.thetvdb.com/api/" & tvdbAPIID & "/series/" & SeriesID.ToString & "/all/en.xml"
        SeriesData = GetWebData(url)

        'Write XML to file
        SeriesXML = New FileStream(TempDir & "temp.xml", FileMode.Create)
        SeriesXML.Write(SeriesData, 0, SeriesData.Length)
        SeriesXML.Close()

        'Search XML for correct season number and episode number using episode name
        xpathDoc = New XPathDocument(TempDir & "temp.xml")
        xmlNav = xpathDoc.CreateNavigator
        xmlNI = xmlNav.Select("//EpisodeName[contains(.,""" & EpisodeName & """)]/parent::node()/SeasonNumber")
        Do While xmlNI.MoveNext
            If CInt(xmlNI.Current.Value) <> 0 Then
                EpisodeData(0) = CInt(xmlNI.Current.Value)
            End If
        Loop
        xmlNI = xmlNav.Select("//EpisodeName[contains(.,""" & EpisodeName & """)]/parent::node()/EpisodeNumber")
        Do While xmlNI.MoveNext
            If CInt(xmlNI.Current.Value) <> 0 Then
                EpisodeData(1) = CInt(xmlNI.Current.Value)
            End If
        Loop

        'Delete xml file and return season number & episode number
        File.Delete(TempDir & "temp.xml")

        Return EpisodeData
    End Function

    Public Function GetTVPoster(ByVal SeriesID As Long) As String
        Dim BannerData() As Byte
        Dim BannerXML As FileStream
        Dim BannerPath As String
        Dim url As String
        Dim PosterData() As Byte
        Dim BannerSplit() As String
        Dim FileName As String = ""
        Dim PosterWrite As FileStream
        Dim xpathDoc As XPathDocument
        Dim xmlNav As XPathNavigator
        Dim xmlNI As XPathNodeIterator

        'Use TVDB series ID to get the banners.xml file
        url = "http://www.thetvdb.com/api/" & tvdbAPIID & "/series/" & SeriesID.ToString & "/banners.xml"
        BannerData = GetWebData(url)

        'Write XML to file
        BannerXML = New FileStream(TempDir & "temp.xml", FileMode.Create)
        BannerXML.Write(BannerData, 0, BannerData.Length)
        BannerXML.Close()

        'Open XML file and get the path to all files with the banner type "poster"
        xpathDoc = New XPathDocument(TempDir & "temp.xml")
        xmlNav = xpathDoc.CreateNavigator
        xmlNI = xmlNav.Select("//BannerType[. = 'poster']/parent::node()/BannerPath")

        'Get only the path to the first poster
        xmlNI.MoveNext()
        BannerPath = xmlNI.Current.Value

        'Download poster and write file to temp folder
        If BannerPath <> String.Empty Then
            url = "http://www.thetvdb.com/banners/" & BannerPath
            PosterData = GetWebData(url)
            BannerSplit = Split(BannerPath, "/")
            FileName = TempDir & BannerSplit(1)
            PosterWrite = New FileStream(FileName, FileMode.Create)
            PosterWrite.Write(PosterData, 0, PosterData.Length)
            PosterWrite.Close()
        End If

        'Delete XML temp file and return the poster filename
        File.Delete(TempDir & "temp.xml")
        Return FileName
    End Function

    Public Function GetMovieID(ByVal Title As String, Optional ByVal Year As String = "") As String()
        Dim URLTitle As String
        Dim url As String
        Dim MovieData() As Byte
        Dim FileWrite As FileStream
        Dim xpathDoc As XPathDocument
        Dim xmlNav As XPathNavigator
        Dim xmldoc As XmlDocument = New XmlDocument
        Dim nsMgr As XmlNamespaceManager
        Dim xmlNI As XPathNodeIterator
        Dim Result As Integer
        Dim TMDbID() As String = {"", String.Empty}

        'Replace spaces in movie title with +'s and, create URL, and get data
        URLTitle = Title.Replace(" ", "+")
        url = "http://api.themoviedb.org/2.1/Movie.search/en/xml/" & tmdbAPIKey & "/" & URLTitle
        MovieData = GetWebData(url)

        'Write data to temporary XML file
        FileWrite = New FileStream(TempDir & "temp.xml", FileMode.Create)
        FileWrite.Write(MovieData, 0, MovieData.Length)
        FileWrite.Close()

        'Open XML file
        xpathDoc = New XPathDocument(TempDir & "temp.xml")
        xmlNav = xpathDoc.CreateNavigator
        nsMgr = New XmlNamespaceManager(xmlNav.NameTable)
        nsMgr.AddNamespace("opensearch", "http://a9.com/-/spec/opensearch/1.1/")

        If Year <> "" Then 'If the year of the movie was captured use the Title and Year to search XML
            'Check to make sure there were results first
            xmlNI = xmlNav.Select("/OpenSearchDescription/opensearch:totalResults", nsMgr)
            xmlNI.MoveNext()
            Result = CInt(xmlNI.Current.Value)
            'If Result <> "Nothing found." Then
            If Result > 0 Then
                xmlNI = xmlNav.Select("/OpenSearchDescription/movies/movie[contains(name,""" & Title & """) and contains(released,'" & Year & "')]/id")
            Else
                Return TMDbID
                Exit Function
            End If
        Else 'Otherwise get all TMDB ID's
            'Check to make sure there were results first
            xmlNI = xmlNav.Select("/OpenSearchDescription/opensearch:totalResults", nsMgr)
            xmlNI.MoveNext()
            Result = CInt(xmlNI.Current.Value)
            'If Result <> "Nothing found." Then
            If Result > 0 Then
                xmlNI = xmlNav.Select("/OpenSearchDescription/movies/movie/name[. = """ & Title & """]/parent::node()/id")
            Else
                Return TMDbID
                Exit Function
            End If
        End If

        If xmlNI.Count = 1 Then 'Only get the TMDB ID if there is one result, otherwise we don't want to get the wrong ID
            Do While xmlNI.MoveNext
                TMDbID(0) = xmlNI.Current.Value
            Loop
        Else
            SelectedID(0) = String.Empty
            xmlNI = xmlNav.Select("/OpenSearchDescription/movies/movie/name")
            ReDim Selections((xmlNI.Count - 1), 2)
            Dim x As Integer = 0
            Do While xmlNI.MoveNext
                Selections(x, 0) = xmlNI.Current.Value
                x += 1
            Loop
            xmlNI = xmlNav.Select("/OpenSearchDescription/movies/movie/released")
            x = 0
            Do While xmlNI.MoveNext
                Selections(x, 1) = xmlNI.Current.Value
                x += 1
            Loop
            xmlNI = xmlNav.Select("/OpenSearchDescription/movies/movie/id")
            x = 0
            Do While xmlNI.MoveNext
                Selections(x, 2) = xmlNI.Current.Value
                x += 1
            Loop
            frmTitleSelect.ShowDialog()
            If SelectedID(0) <> String.Empty Then
                TMDbID = SelectedID
            End If
        End If
        'Delete temp file
        File.Delete(TempDir & "temp.xml")
        'Return the TMDB ID
        Return TMDbID
    End Function

    Public Function GetMoviePoster(ByVal TMDbID As String) As String
        Dim url As String
        Dim PosterData() As Byte
        Dim FileWrite As FileStream
        Dim xpathDoc As XPathDocument
        Dim xmlNav As XPathNavigator
        Dim xmlNI As XPathNodeIterator
        Dim PosterURL As String
        Dim PosterSplit() As String
        Dim FileName As String
        Dim PosterWrite As FileStream

        'Use the TMDB ID to get the list of images for the movie
        url = "http://api.themoviedb.org/2.1/Movie.getImages/en/xml/" & tmdbAPIKey & "/" & TMDbID
        PosterData = GetWebData(url)

        'Write XML to file
        FileWrite = New FileStream(TempDir & "temp.xml", FileMode.Create)
        FileWrite.Write(PosterData, 0, PosterData.Length)
        FileWrite.Close()

        'Open XML file and get the URL's for all poster images
        xpathDoc = New XPathDocument(TempDir & "temp.xml")
        xmlNav = xpathDoc.CreateNavigator
        xmlNI = xmlNav.Select("/OpenSearchDescription/movies/movie/images/poster/image[@size='mid']/@url")

        'Get the URL for the first poster image
        xmlNI.MoveNext()
        PosterURL = xmlNI.Current.Value

        'Delete Temp file
        File.Delete(TempDir & "temp.xml")

        'Get poster file
        PosterData = GetWebData(PosterURL)

        'Get only filename using the poster URL
        PosterSplit = Split(PosterURL, "/")
        FileName = TempDir & PosterSplit(PosterSplit.Length - 1)

        'Write downloaded file to temp folder
        PosterWrite = New FileStream(FileName, FileMode.Create)
        PosterWrite.Write(PosterData, 0, PosterData.Length)
        PosterWrite.Close()

        'Return name of poster file
        Return FileName
    End Function

    Public Sub iTunesExport(ByVal FilePath As String)
        Dim iTunes As New iTunesApp
        Dim Tracks = iTunes.LibraryPlaylist
        Dim AddVideo = Tracks.AddFile(FilePath)

        Do
        Loop While AddVideo.InProgress = True
    End Sub
End Module
